在伺服器的控制器(ZK composer)載入資料後,要讓它跟 zul 上寫的元件關聯,才能實際控制 zul上的元件,於是我在最上層的元件 <div>
上的 apply
寫上完整 class 名稱:
<div width="20%" apply="quickstart.hero.HeroController" style="margin: 0 auto">
<h:h3>復仇者英雄列表</h:h3>
<listbox id="heroBox" rows="5" emptyMessage="無資料">
...
</listbox>
當我想控制 <div>
跟其下子元件時,我就必須將控制器關聯到該元件。
控制器的生命週期是由 ZK 決定,因此你無需寫程式去產生該物件。當一個瀏覽器訪問這個 zul 時,ZK 就會新建一個控制器物件,並呼叫對應的生命週期方法,如 doAfterCompose()
,也會剖析 zul 檔將對應的元件生成,並綁定到我所指定的控制器上去。
要用 Listbox 顯示資料前先了解 ZK 針對資料元件(例如Listbox, Grid, Tree)及一些支援 model
屬性的元件(如 Tabbox, Selectbox, Searchbox等)的設計架構都是採用「資料模型驅動繪製」。元件(Listbox)、zul、資料模型(ListModel),3者之間形成 MVC pattern。
以 Listbox
為例,開發者把資料模型 (ListModelList
) 塞給元件 (Listbox
),元件根據模板或繪製器 (<template>
, ListItemRender
) 生成其對應的子元件 (Listitem
)。開發者需透過操控資料模型(ListModel)的內容來控制子元件而不是直接生成/消滅子元件。
add()
, remove()
, clear()
被呼叫時setModel()
只是將資料塞給 Listbox
,預設 Listbox
會呼叫 toString()
把每個 Hero
繪製出來,但這通常不是我們想要的。因此我要定義一個範本來決定怎麼繪製每一個 Hero 物件,語法如下:
<listbox id="heroBox" rows="5" emptyMessage="無資料" >
<listhead>
<listheader width="50px"/>
<listheader />
</listhead>
<template name="model">
<listitem>
<listcell label="${forEachStatus.index}"/>
<listcell label="${each.name}"/>
</listitem>
</template>
</listbox>
<listheader>
控制欄位寬度<template>
用來定義範本,name
的值必須是 model
,代表是給 model
用的範本。${each}
是 ZK 預設定義的隱含變數,代表 model 中的每個物件,在我們的例子中是 Hero
,用 dot notation 來存取 Java bean 物件上的屬性如 ${each.name}
${forEachStatus.index}
也是隱含變數,用來存取model索引值,從0 開始